package com.lyb269.thread;


import org.junit.Test;

/**
 * 线程Thread 6种状态的变化过程
 */
public class ThreadStateTest {

    @Test
    public void startTest() throws InterruptedException {
        System.out.println("== StartTest Start ==");
        Thread t = new Thread(() ->{
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName +" ---> Running");
        });
        System.out.println(t.getState().name()); //NEW 初始化
        t.start();
        System.out.println(t.getState().name()); // start(); 变为RUNNABLE 可执行
        Long startTime = System.currentTimeMillis();
        while (t.isAlive()){
            //等待线程执行完毕
        }
        System.out.println(t.getName()+"执行使用了:"+(System.currentTimeMillis()-startTime)+"ms");
        System.out.println(t.getState().name());
        System.out.println("== StartTest End ==");
        //打印结果
        //== StartTest Start ==
        //NEW                       线程处于初始化的阶段
        //RUNNABLE                  调用start(), 程准备就绪,可运行,等待处理器分配资源执行
        //Thread-0 ---> Running     线程执行
        //Thread-0执行使用了:0ms     执行run方法使用时间
        //TERMINATED                线程执行完毕
        //== StartTest End ==
    }

    @Test
    public void stateChangeProcessForTimeWait() throws InterruptedException{

        Thread t = new Thread(() -> {
            Thread currentThread = Thread.currentThread();
            System.out.println("start()执行后;状态为:"+currentThread.getState().name());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("sleep()执行后;状态为:"+currentThread.getState().name());
        });
        System.out.println("start()执行前;状态为:"+t.getState().name());
        //start
        t.start();
        //另起一个线程,比线程t短,此线程sleep结束,t线程还在sleep
        Thread.sleep(500);
        System.out.println("sleep()执行过程中;状态为:"+t.getState().name());
        while (t.isAlive()){
            // 循环判断,直到线程执行结束
        }
        System.out.println("线程执行完毕;状态为:"+t.getState().name());

        //start()执行前;状态为:NEW                    初始化阶段:NEW
        //start()执行后;状态为:RUNNABLE               可运行阶段:RUNNABLE
        //sleep()执行过程中;状态为:TIMED_WAITING       主动sleep
        //sleep()执行后;状态为:RUNNABLE               等待时长结束,恢复可运行阶段,等待CPU分配执行
        //线程执行完毕;状态为:TERMINATED               执行结束
    }

    @Test
    public void stateChangeProcessForWait() throws InterruptedException{
        //定义一个锁,这里直接使用obj,用来加解锁
        Object lock = new Object();
        Thread t = new Thread(() -> {
            Thread currentThread = Thread.currentThread();
            System.out.println("start()执行后;状态为:"+currentThread.getState().name());
            synchronized (lock){
                try {
                    //模拟1秒业务操作
                    Thread.sleep(1000);
                    //wait,等待notify
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("notify()执行后;状态为:"+currentThread.getState().name());
        });
        System.out.println("start()执行前;状态为:"+t.getState().name());
        //start
        t.start();
        //另起一个线程,比线程t长,保证t线程正常wait
        Thread.sleep(1500);
        System.out.println("wait()执行后;状态为:"+t.getState().name());
        // notify
        new Thread(() -> {
            synchronized (lock){
                // 唤醒
                lock.notify();
            }
        }).start();
        while (t.isAlive()){
            // 循环判断,直到线程执行结束
        }
        System.out.println("线程执行完毕;状态为:"+t.getState().name());


        //start()执行前;状态为:NEW           初始化阶段
        //start()执行后;状态为:RUNNABLE      可运行阶段,等待操作系统执行
        //wait()执行后;状态为:WAITING        释放锁,进入wait,等待notify
        //notify()执行后;状态为:RUNNABLE     notify,唤醒wait线程,重新变成可运行
        //线程执行完毕;状态为:TERMINATED      执行结束
    }

    @Test
    public void stateChangeProcessForBlock() throws InterruptedException{
        //定义一个锁,这里直接使用obj,用来加解锁
        Object lock = new Object();
        new Thread(() -> {
            synchronized (lock){
                try {
                    //模拟业务逻辑,占用锁 2000ms
                    Thread.sleep(2000);
                    // 进入wait
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Thread t = new Thread(() -> {
            Thread current = Thread.currentThread();
            System.out.println("start()执行后;状态为:"+current.getState().name());
            synchronized (lock){
                try {
                    // 模拟业务,占用锁 1000ms
                    Thread.sleep(1000);
                    // 唤醒
                    lock.notify();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("阻塞结束,线程的状态为:"+current.getState().name());
        });

        System.out.println("start()执行前;状态为:"+t.getState().name());
        //start
        t.start();
        //此线程sleep结束,第一个线程还在sleep,t线程发在等待获取锁而阻塞
        Thread.sleep(1000);
        System.out.println("等待获取锁而阻塞;状态为:"+t.getState().name());
        while (t.isAlive()){
            // 循环判断,直到线程执行结束
        }
        System.out.println("线程执行完毕;状态为:"+t.getState().name());

        //start()执行前;状态为:NEW            初始化阶段
        //start()执行后;状态为:RUNNABLE       可运行阶段,等待操作系统执行
        //等待获取锁而阻塞;状态为:BLOCKED      等待获取锁,而发生阻塞
        //阻塞结束,线程的状态为:RUNNABLE       获取到锁,阻塞结束,变成可运行状态,等待执行
        //线程执行完毕;状态为:TERMINATED       执行结束
    }


}
